const jwt = require('jsonwebtoken');
const { promisify } = require('util');
const { User } = require('../models');
const { AppError } = require('./errorHandler');
const logger = require('../utils/logger');

// 验证JWT令牌
const protect = async (req, res, next) => {
  try {
    // 1) 获取令牌并检查是否存在
    let token;
    if (
      req.headers.authorization &&
      req.headers.authorization.startsWith('Bearer')
    ) {
      token = req.headers.authorization.split(' ')[1];
    }

    if (!token) {
      return next(
        new AppError('您未登录，请先登录以获取访问权限', 401)
      );
    }

    // 2) 验证令牌
    const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);

    // 3) 检查用户是否仍然存在
    const currentUser = await User.findByPk(decoded.id);
    if (!currentUser) {
      return next(
        new AppError('该令牌的用户不再存在', 401)
      );
    }

    // 4) 检查用户是否被禁用
    if (!currentUser.active) {
      return next(
        new AppError('您的账户已被禁用，请联系管理员', 401)
      );
    }

    // 5) 检查用户是否在令牌发出后更改了密码
    if (currentUser.changedPasswordAfter(decoded.iat)) {
      return next(
        new AppError('用户最近更改了密码，请重新登录', 401)
      );
    }

    // 授权访问受保护的路由
    req.user = currentUser;
    next();
  } catch (error) {
    logger.error('认证错误:', error);
    return next(new AppError('认证失败', 401));
  }
};

// 限制访问权限（基于角色）
const restrictTo = (...roles) => {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      return next(
        new AppError('您没有权限执行此操作', 403)
      );
    }
    next();
  };
};

// 可选认证（不强制要求登录）
const optionalAuth = async (req, res, next) => {
  try {
    let token;
    if (
      req.headers.authorization &&
      req.headers.authorization.startsWith('Bearer')
    ) {
      token = req.headers.authorization.split(' ')[1];
    }

    if (token) {
      const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);
      const currentUser = await User.findByPk(decoded.id);
      
      if (currentUser && currentUser.active && !currentUser.changedPasswordAfter(decoded.iat)) {
        req.user = currentUser;
      }
    }
    
    next();
  } catch (error) {
    // 忽略认证错误，继续执行
    next();
  }
};

// 验证用户是否为资源所有者或管理员
const checkOwnership = (resourceModel, resourceIdParam = 'id', ownerField = 'userId') => {
  return async (req, res, next) => {
    try {
      const resourceId = req.params[resourceIdParam];
      const resource = await resourceModel.findByPk(resourceId);
      
      if (!resource) {
        return next(new AppError('资源不存在', 404));
      }
      
      // 管理员可以访问所有资源
      if (req.user.role === 'admin') {
        req.resource = resource;
        return next();
      }
      
      // 检查是否为资源所有者
      const ownerId = resource[ownerField] || resource.customerId || resource.ownerId;
      const isOwner = ownerId && ownerId === req.user.id;
      
      if (!isOwner) {
        return next(new AppError('您只能访问自己的资源', 403));
      }
      
      req.resource = resource;
      next();
    } catch (error) {
      logger.error('权限检查错误:', error);
      return next(new AppError('权限检查失败', 500));
    }
  };
};

module.exports = {
  protect,
  restrictTo,
  optionalAuth,
  checkOwnership
};